//
//  PlSCFPreferences.m
//  Injector
//
//  Created by ∞ on 10/12/07.
//  Copyright 2007 Emanuele Vulcano (infinite-labs.net). All rights reserved.
//

#import "PlSCFPreferences.h"
#import <CoreFoundation/CoreFoundation.h>

@interface PlSCFPreferences ()

- (void) _didChangePreferences:(NSNotification*) n;

@end

@implementation PlSCFPreferences

- (id) init {
	if (self = [super init]) {
		[[NSDistributedNotificationCenter defaultCenter]
		 addObserver:self selector:@selector(_didChangePreferences:) name:kPlSPreferencesChangedNotification object:kPlSDistributedObjectName];
	}
	
	return self;
}

- (void) dealloc {
	[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
	[super dealloc];
}

- (BOOL) isPlugInIdentifierDisabled:(NSString*) ident {
	return [self isIdentifier:ident disabledInKey:kPlSDisabledPlugInIdentifiersKey];
}

- (BOOL) isIdentifier:(NSString*) ident disabledInKey:(NSString*) key {
	NSDictionary* dict;
	dict = (NSDictionary*) CFPreferencesCopyAppValue((CFStringRef) key, 
													 (CFStringRef) kPlSPreferencesIdentifier);
	
	return [[[dict autorelease] objectForKey:ident] boolValue]? YES : NO;
}

- (void) setDisabled:(BOOL) pref forPlugInIdentifier:(NSString*) identifier {
	[self setDisabled:pref forIdentifier:identifier inKey:kPlSDisabledPlugInIdentifiersKey];
}

- (void) setDisabled:(BOOL) pref forIdentifier:(NSString*) identifier inKey:(NSString*) key {
	NSDictionary* currentDict;
	currentDict = (NSDictionary*)
		CFPreferencesCopyAppValue((CFStringRef) key,
								  (CFStringRef) kPlSPreferencesIdentifier);
	
	L0Log(@"current dict = %@", currentDict);
	
	NSMutableDictionary* dict;
	
	if (currentDict) {
		dict = [NSMutableDictionary dictionaryWithDictionary:currentDict];
		[currentDict release];
	} else
		dict = [NSMutableDictionary dictionary];
	
	if (pref)
		[dict setObject:[NSNumber numberWithBool:YES] forKey:identifier];
	else
		[dict removeObjectForKey:identifier];
	
	CFPreferencesSetAppValue((CFStringRef) key,
							 (CFPropertyListRef) dict,
							 (CFStringRef) kPlSPreferencesIdentifier);
	[self _didChangePreferences:nil];
	[self notifyPreferencesChanged];
	
	L0Log(@"set disabled = %d for identifier = %@ in key = %@", pref, identifier, key);
}

- (void) _didChangePreferences:(NSNotification*) n {
	CFPreferencesAppSynchronize((CFStringRef) kPlSPreferencesIdentifier);
}

- (void) notifyPreferencesChanged {
	CFPreferencesAppSynchronize((CFStringRef) kPlSPreferencesIdentifier);
	[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kPlSPreferencesChangedNotification object:kPlSDistributedObjectName userInfo:nil deliverImmediately:YES];
}

- (BOOL) isApplicationExcluded:(NSBundle*) app {
	if (![app bundleIdentifier]) return NO;
	return [self isIdentifier:[app bundleIdentifier] disabledInKey:kPlSExcludedApplicationIdentifiersKey] || [self isIdentifier:[app bundlePath] disabledInKey:kPlSExcludedApplicationPathsKey];
}

- (BOOL) setExcluded:(BOOL) pref forApplication:(NSBundle*) app {
	if ([app bundleIdentifier]) {
		[self setDisabled:pref forIdentifier:[app bundleIdentifier] inKey:kPlSExcludedApplicationIdentifiersKey];
		[self setDisabled:pref forIdentifier:[app bundlePath] inKey:kPlSExcludedApplicationPathsKey];
		return YES;
	} else
		return NO;
}

- (NSArray*) excludedApplicationIdentifiers {
	return [self identifiersExcludedForKey:kPlSExcludedApplicationIdentifiersKey];
}

- (NSArray*) identifiersExcludedForKey:(NSString*) key {
	NSDictionary* currentDict;
	currentDict = (NSDictionary*)
	CFPreferencesCopyAppValue((CFStringRef) key,
							  (CFStringRef) kPlSPreferencesIdentifier);
	[currentDict autorelease];
	NSMutableArray* arr = [NSMutableArray array];
	for (NSString* key in currentDict) {
		if ([[currentDict objectForKey:key] boolValue])
			[arr addObject:key];
	}
	
	L0Log(@"identifiers excluded for key = %@ are = %@", key, arr);
	return arr;
}

- (NSArray*) excludedApplicationPaths {
	return [self identifiersExcludedForKey:kPlSExcludedApplicationPathsKey];
}

- (NSDate*) lastUpdateCheckDate {
	NSDate* date = (NSDate*) CFPreferencesCopyAppValue((CFStringRef) kPlSLastUpdateCheckDateKey, (CFStringRef) kPlSPreferencesIdentifier);
	return [date autorelease];
}

- (void) markNowAsLastUpdateCheckDate {
	CFPreferencesSetAppValue((CFStringRef) kPlSLastUpdateCheckDateKey, (CFPropertyListRef) [NSDate date], (CFStringRef) kPlSPreferencesIdentifier);
}

- (BOOL) checkForPlugSuitUpdates {
	id x = (id) CFPreferencesCopyAppValue((CFStringRef) kPlSCheckForPlugSuitUpdatesKey, (CFStringRef) kPlSPreferencesIdentifier);
	[x autorelease];
	
	return x? [x boolValue] : NO;
}

- (BOOL) checkForPlugInUpdates {
	id x = (id) CFPreferencesCopyAppValue((CFStringRef) kPlSCheckForPlugInUpdatesKey, (CFStringRef) kPlSPreferencesIdentifier);
	[x autorelease];
	
	return x? [x boolValue] : NO;
}

- (void) setCheckForPlugSuitUpdates:(BOOL) check {
	CFPreferencesSetAppValue((CFStringRef) kPlSCheckForPlugSuitUpdatesKey, (CFPropertyListRef) [NSNumber numberWithBool:check], (CFStringRef) kPlSPreferencesIdentifier);
}

- (void) setCheckForPlugInUpdates:(BOOL) check {
	CFPreferencesSetAppValue((CFStringRef) kPlSCheckForPlugInUpdatesKey, (CFPropertyListRef) [NSNumber numberWithBool:check], (CFStringRef) kPlSPreferencesIdentifier);
}

- (BOOL) isCheckingForUpdates {
	return self.checkForPlugSuitUpdates || self.checkForPlugInUpdates;
}

+ (void) initialize {
	[self setKeys:[NSArray arrayWithObjects:@"checkForPlugSuitUpdates", @"checkForPlugInUpdates", nil] triggerChangeNotificationsForDependentKey:@"isCheckingForUpdates"];
}

- (BOOL) boolForKey:(NSString*) key defaultValue:(BOOL) def {
	NSNumber* ref = (NSNumber*) CFPreferencesCopyAppValue((CFStringRef) key, (CFStringRef) kPlSPreferencesIdentifier);
	[ref autorelease];
	
	if (!ref) return def; else return [ref boolValue];
}

- (void) setBool:(BOOL) val forKey:(NSString*) key {
	CFPreferencesSetAppValue((CFStringRef) key, (CFPropertyListRef) [NSNumber numberWithBool:val], (CFStringRef) kPlSPreferencesIdentifier);
}

- (BOOL) shouldTryEnabling {
	return [self boolForKey:kPlSShouldTryEnablingOnDisplayKey defaultValue:NO];
}

- (void) setShouldTryEnabling:(BOOL) enabling {
	[self setBool:enabling forKey:kPlSShouldTryEnablingOnDisplayKey];
}

@end
